package top.jacktgq.itheima.netty.protocol_design.groupchat.protocol.serializer;

import top.jacktgq.utils.JsonUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * @Author CandyWall
 * @Date 2021/3/25--10:13
 * @Description 用于扩展序列化、反序列化算法
 */
public interface Serializer {
    /**
     * 反序列化方法
     *
     * @param clazz ：需要序列化转成的Java类
     * @param bytes ：待反序列化的字节数组
     * @return
     */
    <T> T deserialize(Class<T> clazz, byte[] bytes);

    /**
     * 序列化方法
     *
     * @param object ：待序列化的java对象
     * @return
     */
    <T> byte[] serialize(T object);

    enum Algorithm implements Serializer {
        Java {
            @Override
            public <T> T deserialize(Class<T> clazz, byte[] bytes) {
                try {
                    ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
                    return (T) ois.readObject();
                } catch (IOException | ClassNotFoundException e) {
                    throw new RuntimeException("反序列化失败！", e);
                }
            }

            @Override
            public <T> byte[] serialize(T object) {
                try {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    ObjectOutputStream oos = new ObjectOutputStream(baos);
                    oos.writeObject(object);
                    return baos.toByteArray();
                } catch (IOException e) {
                    throw new RuntimeException("序列化失败！", e);
                }
            }
        },

        Json {
            @Override
            public <T> T deserialize(Class<T> clazz, byte[] bytes) {
                try {
                    return JsonUtils.json2pojo(new String(bytes, StandardCharsets.UTF_8), clazz);
                } catch (Exception e) {
                    throw new RuntimeException("反序列化失败！", e);
                }
            }

            @Override
            public <T> byte[] serialize(T object) {
                try {
                    return JsonUtils.obj2json(object).getBytes(StandardCharsets.UTF_8);
                } catch (Exception e) {
                    throw new RuntimeException("序列化失败！", e);
                }
            }
        }
    }
}
